package emas.client.handler;

import java.sql.Timestamp;
import java.util.ArrayList;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;

import emas.client.RetrieveDataService;
import emas.client.RetrieveDataServiceAsync;
import emas.client.userinterface.LocationTabContent;
import emas.client.userinterface.TabLayout;
import emas.shared.Location;
import emas.shared.SensorData;

public class DataHandler {

	private RetrieveDataServiceAsync retrieveDataService;

	private TabLayout tabLayout = null;

	private UpdateHandler updateHandler;

	public DataHandler(TabLayout layout) {
		retrieveDataService = (RetrieveDataServiceAsync) GWT
				.create(RetrieveDataService.class);
		tabLayout = layout;
		updateHandler = new UpdateHandler(this);
		if (!isDevelopmentMode()) {
			startUpdateHandler();
		}
	}

	public void getLocations() {
		retrieveLocations();
	}

	private void retrieveLocations() {

		AsyncCallback<ArrayList<Location>> callback = new AsyncCallback<ArrayList<Location>>() {
			public void onFailure(Throwable caught) {
			}

			@Override
			public void onSuccess(ArrayList<Location> result) {
				tabLayout.updateSummaryData(result);
			}
		};
		System.out.println("Updating Locations...");
		retrieveDataService.getLocations(callback);
	}

	public void startUpdateHandler() {
		updateHandler.startUpdateHandler();
	}

	public void stopUpdateHandler() {
		updateHandler.stopUpdateHandler();
	}

	public void addLocation(Location location) {
		AsyncCallback<Void> asyncCallback = new AsyncCallback<Void>() {

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Add Failure");
			}

			@Override
			public void onSuccess(Void result) {
				Window.alert("Add Successful");
				getLocations();
			}
		};
		retrieveDataService.addLocation(location, asyncCallback);
	}

	public void removeLocation(Location location) {
		AsyncCallback<Void> asyncCallback = new AsyncCallback<Void>() {

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Remove Failure");
			}

			@Override
			public void onSuccess(Void result) {
				Window.alert("Remove Successful");
				getLocations();
			}
		};
		retrieveDataService.removeLocation(location, asyncCallback);
	}

	public void updateLocation(Location location) {
		AsyncCallback<Void> asyncCallback = new AsyncCallback<Void>() {

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Update Failure");
			}

			@Override
			public void onSuccess(Void result) {
				Window.alert("Update Successful");
				getLocations();
			}
		};
		retrieveDataService.updateLocation(location, asyncCallback);
	}

	public void getUserFromSession() {
		transferLogintoServer(null, null);
	}

	public void transferLogintoServer(final String username,
			final String password) {
		AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>() {

			@Override
			public void onFailure(Throwable caught) {

			}

			@Override
			public void onSuccess(Boolean result) {
				tabLayout.setUserAuthenticated(result.booleanValue());
			}
		};

		retrieveDataService.authenticateUser(username, password, callback);
	}

	public void updateCurrentlyAuthenticatedUser() {
		AsyncCallback<String> callback = new AsyncCallback<String>() {

			@Override
			public void onFailure(Throwable caught) {

			}

			@Override
			public void onSuccess(String result) {
				tabLayout.updateCurrentlyAuthenticatedUser(result);
			}
		};

		retrieveDataService.getCurrentlyAuthenticatedUser(callback);
	}

	private boolean isDevelopmentMode() {
		return !GWT.isScript() && GWT.isClient();
	}

	public void getSensorDataForLocationSensor(Location location,
			String sensor, final ArrayList<SensorData> sensorData) {

	}

	public void getSensorDataForLocationIntervall(Location location,
			Timestamp fromDate, Timestamp toDate,
			final LocationTabContent locationTabContent) {
		AsyncCallback<ArrayList<SensorData>> callback = new AsyncCallback<ArrayList<SensorData>>() {

			@Override
			public void onFailure(Throwable caught) {

			}

			@Override
			public void onSuccess(ArrayList<SensorData> result) {
				locationTabContent.updateSensorData(result);
			}
		};

		retrieveDataService.getSensorDataForLocationIntervall(location,
				fromDate, toDate, callback);
	}
}
